package com.jandan.ui.server;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.gwtwidgets.server.spring.ServletUtils;

import com.jandan.logic.JWordzFacade;
import com.jandan.ui.client.service.LessonService;
import com.jandan.ui.model.LearnedData;
import com.jandan.ui.model.LearnedWord;
import com.jandan.ui.model.Lesson;
import com.jandan.ui.model.ReviewInfo;
import com.jandan.ui.model.SmallWordLibInfo;
import com.jandan.ui.model.Word;
import com.jandan.ui.model.WordLib;
import com.jandan.web.front.UserSession;

public class LessonServiceImpl implements LessonService {
	private JWordzFacade jwordz;

	public void setJwordz(JWordzFacade jwordz) {
		this.jwordz = jwordz;
	}

	public List<Lesson> getLessonList() {
		// TODO
		// Auto-generated method stub
		HttpSession session = ServletUtils.getRequest().getSession(true);
		UserSession userSession = (UserSession) session
				.getAttribute("userSession");
		if (userSession != null) {

			List<Lesson> lessonList = jwordz.getLessonListByUserID(userSession
					.getAccount().getUserID());
			Lesson lesson = null;
			for (Iterator<Lesson> it = lessonList.iterator(); it.hasNext();) {
				lesson = it.next();
				lesson.setSmallWordLibList(this
						.getSmallWordLibInfoListOfLesson(lesson));
			}

			return lessonList;
		}
		return null;
	}

	public Lesson insertLesson(Lesson lesson) {
		// TODO Auto-generated method stub
		HttpSession session = ServletUtils.getRequest().getSession(true);
		UserSession userSession = (UserSession) session
				.getAttribute("userSession");
		if (userSession != null) {
			lesson.setUserID(userSession.getAccount().getUserID());
			long lessonID = jwordz.insertLesson(lesson);
			
			lesson = jwordz.getLessonByLessonID(lessonID);
//			lesson.setLessonID(lessonID);
//			lesson.setWordLib(jwordz.getWordLibByWordLibID(lesson.getWordLibID()));
			lesson.setSmallWordLibList(this
					.getSmallWordLibInfoListOfLesson(lesson));
			return lesson;
		}
		return null;
	}

	public void deleteLesson(long lessonID) {
		// TODO Auto-generated method stub
		jwordz.deleteLesson(lessonID);
	}

	public Lesson getLesson(long lessonID) {
		// TODO Auto-generated method stub
		Lesson lesson = jwordz.getLessonByLessonID(lessonID);
		lesson
				.setSmallWordLibList(this
						.getSmallWordLibInfoListOfLesson(lesson));
		return lesson;
	}

	public void writeback(List<LearnedWord> learnedWordList) {
		// TODO Auto-generated method stub
		if (learnedWordList != null) {
			LearnedWord lw = null;
			for (Iterator<LearnedWord> it = learnedWordList.iterator(); it
					.hasNext();) {
				lw = it.next();
				if (lw != null)
					jwordz.insertOrUpdateLearnedWord(lw);
			}
		}
	}

	public List<LearnedWord> getLearnedWordList(long lessonID) {
		// TODO Auto-generated method stub
		return jwordz.getLearnedWordListByLessonID(lessonID);
	}

	private List<SmallWordLibInfo> getSmallWordLibInfoListOfLesson(Lesson lesson) {
		long wordLibID = lesson.getWordLibID();
		int smallLibWordCount = lesson.getWordsCountOfPerSmallLib();

		List<SmallWordLibInfo> smallWordLibList = new ArrayList<SmallWordLibInfo>();
		WordLib wordLib = jwordz.getWordLibByWordLibID(wordLibID);

		if (wordLib != null) {
			int wordCount = jwordz.getTotalWordCountOfWordLib(wordLibID);
			int n = (int) (wordCount / smallLibWordCount);
			SmallWordLibInfo smallWordLib = null;
			Word startWord = null;
			Word endWord = null;
			for (int i = 0; i <= n; i++) {
				int startNumber = i * smallLibWordCount;
				int endNumber = (i + 1) * smallLibWordCount - 1;
				if (i == n) {
					endNumber = wordCount - 1;
				}
				smallWordLib = new SmallWordLibInfo();
				startWord = jwordz.getWordOfOnePositionByWordLibID(
						wordLibID, startNumber);
				endWord = jwordz.getWordOfOnePositionByWordLibID(
						wordLibID, endNumber);
				smallWordLib.setStartWord(startWord.getWordEn());
				smallWordLib.setEndWord(endWord.getWordEn());
 				smallWordLib.setTotalWordCount(endNumber - startNumber + 1);
				smallWordLib.setSmallWordNumber(i);

				smallWordLibList.add(smallWordLib);
			}
		}
		return smallWordLibList;
	}

	public List<Word> getWordListByLessonIDAndLibNumber(long lessonID,
			int libNumber) {
		// TODO Auto-generated method stub
		return jwordz.getWordListByLessonIDAndLibNumber(lessonID, libNumber);
	}

	public List<Word> getNewWordList(long lessonID, int libNumber) {
		// TODO Auto-generated method stub
		return jwordz.getNewWordList(lessonID, libNumber);
	}

	public List<LearnedWord> getLearnedWordList(long lessonID, int libNumber) {
		// TODO Auto-generated method stub
		return jwordz.getLearnedWordListByLessonIDAndLibNumber(lessonID,
				libNumber);
	}

	public Map<String, List> getNewWordAndLearnedWordListByLessonID(
			long lessonID, int libNumber) {
		// TODO Auto-generated method stub
		List<Word> newWordList = this.getNewWordList(lessonID, libNumber);
		List<LearnedWord> learnedWordList = this.getLearnedWordList(lessonID,
				libNumber);

		Map<String, List> map = new HashMap<String, List>();
		map.put("newWordList", newWordList);
		map.put("learnedWordList", learnedWordList);

		return map;
	}

	public List<ReviewInfo> getReviewInfoListByToday(long lessonID) {
		// TODO Auto-generated method stub
		return jwordz.getReviewInfoListByToday(lessonID);
	}

	public ReviewInfo getReviewInfoOfSomeDay(long lessonID,Date date) {
		// TODO Auto-generated method stub
		return jwordz.getReviewInfoOfSomeDay(lessonID,date);
	}

	public ReviewInfo getTodayReviewInfo(long lessonID) {
		// TODO Auto-generated method stub
		return jwordz.getTodayReviewInfo(lessonID);
	}

	public List<ReviewInfo> getReviewInfoList(long lessonID) {
		// TODO Auto-generated method stub
		ReviewInfo todayReviewInfo = jwordz.getTodayReviewInfo(lessonID);
		
		List<ReviewInfo> reviewInfoList = jwordz.getReviewInfoListByToday(lessonID);
		
		if(todayReviewInfo == null){
			todayReviewInfo = new ReviewInfo(new Date(),0);
		}
		
		reviewInfoList.add(0, todayReviewInfo);
		
		return reviewInfoList;
	}

	public List<LearnedWord> getTodayReviewLearnedWordList(long lessonID) {
		// TODO Auto-generated method stub
		List<LearnedWord> learnedWordList = jwordz.getLearnedWordListByLessonIDAndDate(lessonID,new Date());
		
		return learnedWordList;
	}

	public List<LearnedWord> getReviewLearnedWordList(long lessonID,
			List<Date> dateList) {
		// TODO Auto-generated method stub
		List<LearnedWord> learnedWordList = new ArrayList<LearnedWord>();
		Date date = null;
		List<LearnedWord> l = null;
		for(Iterator<Date> it = dateList.iterator();it.hasNext();){
			date = it.next();
			l = jwordz.getLearnedWordListByLessonIDAndDate(lessonID, date);
			learnedWordList.addAll(l);
		}
		return learnedWordList;
	}

	public void updateLesson(Lesson lesson) {
		// TODO Auto-generated method stub
		jwordz.updateLesson(lesson);
	}


	public LearnedData getLearnedData(long lessonID) {
		// TODO Auto-generated method stub
		int totalLearnedWordCount = jwordz.getTotalLearnedWordCount(lessonID);
		int totalMasterWordCount = jwordz.getTotalMasterWordCount(lessonID);
		int totalKnowWordCount = jwordz.getTotalKnowWordCount(lessonID);
		int totalUnknowWordCount = jwordz.getTotalUnknowWordCount(lessonID);
		
		LearnedData l = new LearnedData();
		l.setTotalLearnedWordCount(totalLearnedWordCount);
		l.setTotalMasterWordCount(totalMasterWordCount);
		l.setTotalKnowWordCount(totalKnowWordCount);
		l.setTotalUnknowWordCount(totalUnknowWordCount);
		
		return l;
	}
}
